﻿using System;
using System.Collections.Generic;

using System.Text;
using System.Data.SqlClient;
using System.Diagnostics;
using Estimate.OldSemiCompare.Transfer;
using System.Configuration;
using Estimate.Common;
using Estimate.Common.Repository;
using Estimate.Common.Entity;
using Estimate.Common.DBFieldTypes;
using Estimate.OldSemiCompare;
using System.IO;
using Estimate.Common.Estimate;
using Estimate.Reports;

namespace Estimate.OldSemiCompare
{
    class Program
    {
        public static FileStream logFs;
        public static StreamWriter logSw;


        
        static void Main(string[] args)
        {
            DataImporterCombiner combiner = new DataImporterCombiner(ConfigurationManager.AppSettings);
            combiner.ReCalSemi(new DateTime(2013, 4, 1), new DateTime(2013, 8, 31), ConfigurationManager.AppSettings["NewConnectionString"], new List<ForeRepository>() { ForeRepositoryFactory.NormalCityForeRepository(ConfigurationManager.AppSettings["NewConnectionString"]) });
            Main_Compare(args);
        }





        static void Main_Compare(string[] args)
        {
            string oldConnectionString = ConfigurationManager.AppSettings["OldConnectionString"];
            string newConnectionString = ConfigurationManager.AppSettings["NewConnectionString"]; ;
            string combineConnectionString = ConfigurationManager.AppSettings["CombineConnectionString"]; ;
            
            logFs = new FileStream("06.csv", FileMode.Create);
            logSw = new StreamWriter(logFs);
            execute(oldConnectionString, combineConnectionString);
            combineNormalCityFore(combineConnectionString,newConnectionString);          
            Log("实况日期,实况类型,real,预报日期,fore,分级降水检验,晴雨(雪)检验,一般性降水检验,累加降水量检验");
            compareNormalCityFore(combineConnectionString, newConnectionString);
            logSw.Close();
            logFs.Close();
             
            logFs = new FileStream("06.csv", FileMode.Create);
            logSw = new StreamWriter(logFs);
            exportYanChen(combineConnectionString, newConnectionString, ForeSendpointType.H06);
            logSw.Close();
            logFs.Close();

            logFs = new FileStream("16.csv", FileMode.Create);
            logSw = new StreamWriter(logFs);
            exportYanChen(combineConnectionString, newConnectionString, ForeSendpointType.H16);
            logSw.Close();
            logFs.Close();
        }

        public static void Log(string s)
        {
            Console.WriteLine(s);
            logSw.WriteLine(s+"\n");
        }

        public static void combineNormalCityFore(string oldConnectionString, string newConnectionString)
        {
            Common.Repository.ForeRepository newRepository = Common.Repository.ForeRepositoryFactory.NormalCityForeRepository(newConnectionString);
            Common.Repository.ForeRepository oldRepository = Common.Repository.ForeRepositoryFactory.NormalCityForeRepository(oldConnectionString);
            Repository.ForeRepository combineRepository = new Repository.ForeRepository(oldConnectionString, "CompareCityFore");
            if(! combineRepository.IsTableExist())
                combineRepository.CreateTable();

            DateTime beginDate = new DateTime(2013,1,1);
            DateTime endDate = new DateTime(2013,12,31);
            while(beginDate <= endDate)
            {
                Console.WriteLine("combine date:" + beginDate.ToString("yyyy-MM-dd"));

                foreach (Common.Entity.ForeEntity entity in oldRepository.GetForeRecordWithDateRange(beginDate, beginDate, new ForeClockType[] { ForeClockType.H08, ForeClockType.H20 },
                                                                new ForeSpanType[] { ForeSpanType.FD00_12, ForeSpanType.FD12_24, ForeSpanType.FD00_24,
                                                                                    ForeSpanType.FD24_36,ForeSpanType.FD36_48,ForeSpanType.FD24_48,
                                                                                    ForeSpanType.FD48_60,ForeSpanType.FD60_72,ForeSpanType.FD48_60

                                                                },
                                                                new ForeSendpointType[] { ForeSendpointType.H06, ForeSendpointType.H16 }, new ForeFactorType[] { ForeFactorType.wth }, ForeSemiType.Auto, false))
                {
                    Entity.ForeEntity newEntity = new Entity.ForeEntity(entity,true);
                    combineRepository.SetForeRecord(newEntity,true);
                }

                foreach (Common.Entity.ForeEntity entity in newRepository.GetForeRecordWithDateRange(beginDate, beginDate, new ForeClockType[] { ForeClockType.H08, ForeClockType.H20 },
                                                                new ForeSpanType[] { ForeSpanType.FD00_12, ForeSpanType.FD12_24, ForeSpanType.FD00_24,
                                                                                    ForeSpanType.FD24_36,ForeSpanType.FD36_48,ForeSpanType.FD24_48,
                                                                                    ForeSpanType.FD48_60,ForeSpanType.FD60_72,ForeSpanType.FD48_60

                                                                },
                                                                new ForeSendpointType[] { ForeSendpointType.H06, ForeSendpointType.H16 }, new ForeFactorType[] { ForeFactorType.wth }, ForeSemiType.Auto, false))
                {
                    Entity.ForeEntity newEntity = new Entity.ForeEntity(entity, false);
                    combineRepository.SetForeRecord(newEntity, false);
                }

                beginDate = beginDate.AddDays(1);
            }

            
        }


        public static void exportYanChen(string oldConnectionString, string newConnectionString,ForeSendpointType sendpoint)
        {
            Repository.ForeRepository combineRepository = new Repository.ForeRepository(oldConnectionString, "CompareCityFore");
            DateTime beginDate = new DateTime(2013, 4, 1);
            DateTime endDate = new DateTime(2013, 8, 31);

            RealStationCompareRepository compareRepository = new RealStationCompareRepository(newConnectionString);
            ForeRealStationCompareEntity[] compareEntities = compareRepository.GetAllRecord(RealStationCompareType.Normal_Auto);
            Dictionary<string, string> compareDict = new Dictionary<string, string>();
            RainRealRepository rainRepository = RainRealRepositoryFactory.AutoStationRainRealRepository(newConnectionString);
            foreach (ForeRealStationCompareEntity entity in compareEntities)
            {
                compareDict[entity.ForeStation] = entity.RealStation;
            }
            ForeRealLinker linker = new ForeRealLinker();

            Log(string.Join(",", new string[] { 
                "date",
                "clock",
                "span",
                "sendpoint",
                "factor",
                "semitype",
                "real",
                "fore",
                "old_semi",
                "new_semi",
                "is_diff"
            }));

            while (beginDate <= endDate)
            {
                foreach (Entity.ForeEntity entity in combineRepository.GetForeRecordWithDateRange(beginDate, beginDate, new ForeClockType[] { ForeClockType.H08, ForeClockType.H20 },
                                                                new ForeSpanType[] { ForeSpanType.FD00_12, ForeSpanType.FD12_24, ForeSpanType.FD00_24 },
                                                                new ForeSendpointType[] { sendpoint }, new ForeFactorType[] { ForeFactorType.wth }, ForeSemiType.Auto, false))
                {
                    Dictionary<string, string> oldSemi = new Dictionary<string, string>();
                    Dictionary<string, string> newSemi = new Dictionary<string, string>();


                    RainForeRealCompare comparer = linker.GetForeRelatedRainCondition(entity.Date, entity.Span, entity.Clock);
                    string real = rainRepository.GetValue(comparer.RealDate, comparer.RainType);
                    string stationReal = filterStation(real, compareDict["58354"]);
                    if(stationReal != "")
                        stationReal = stationReal.Split(new char[] { ';' })[1];


                    string stationFore = filterStation(entity.Value, "58354");
                    if(stationFore!="")
                        stationFore = stationFore.Split(new char[] { ';' })[1];

                    string old_semi = filterStation(entity.Semi_old, "58354");
                    if(old_semi!="")
                        old_semi = old_semi.Split(new char[] { ';' })[2];


                    string new_semi = filterStation(entity.Semi_new, "58354");
                    if(new_semi!="")
                        new_semi = new_semi.Split(new char[] { ';' })[2];

                    string is_diff = "";
                    if (old_semi != new_semi)
                        is_diff = "true";

                    Log(string.Join(",", new string[] {
                        entity.Date.ToString("yyyy-MM-dd"),
                        entity.Clock.ToString(),
                        entity.Span.ToString(),
                        entity.Sendpoint.ToString(),
                        entity.Type.ToString(),
                        entity.Semitype.ToString(),
                        stationReal,
                        stationFore,
                        old_semi,
                        new_semi,
                        is_diff
                    }));

                }




                beginDate = beginDate.AddDays(1);
            }
        }

        public static void compareNormalCityFore(string oldConnectionString, string newConnectionString)
        {
            Repository.ForeRepository combineRepository = new Repository.ForeRepository(oldConnectionString, "CompareCityFore");
            DateTime beginDate = new DateTime(2013, 8, 1);
            DateTime endDate = new DateTime(2013, 8, 31);

            while (beginDate <= endDate)
            {
                foreach (Entity.ForeEntity entity in combineRepository.GetForeRecordWithDateRange(beginDate,beginDate, new ForeClockType[] { ForeClockType.H08, ForeClockType.H20 },
                                                                new ForeSpanType[] { ForeSpanType.FD00_12,ForeSpanType.FD12_24, ForeSpanType.FD00_24},
                                                                new ForeSendpointType[] { ForeSendpointType.H06, ForeSendpointType.H10, ForeSendpointType.H16 }, new ForeFactorType[]{ ForeFactorType.wth}, ForeSemiType.Auto, false))
                {
                    Dictionary<string, string> oldSemi = new Dictionary<string, string>();
                    Dictionary<string, string> newSemi = new Dictionary<string, string>();

                    foreach (string s in entity.Semi_old.Split(new char[] { '|' }))
                    {
                        if (s == "")
                            continue;
                        string[] ss = s.Split(new char[]{';'});
                        oldSemi[ss[0]] =  ss[2];
                    }

                    foreach (string s in entity.Semi_new.Split(new char[] { '|' }))
                    {
                        if (s == "")
                            continue;
                        string[] ss = s.Split(new char[] { ';' });
                        newSemi[ss[0]] = ss[2];
                    }

                    foreach (string station in oldSemi.Keys)
                    {
                        string strOld = oldSemi[station];
                        string strNew = "";
                        if (newSemi.ContainsKey(station))
                            strNew = newSemi[station];

                        if (strOld != strNew)
                        {
                            string l = entity.Id.ToString() + " : " + station + " : old -> " + strOld + " , new -> " + strNew;
                            Log(l);
                            printForeRealSemiValue(station,
                                                    entity.Date,
                                                    new ForeClockType[] { entity.Clock },
                                                    new ForeSendpointType[] { entity.Sendpoint },
                                                    new ForeSpanType[] { entity.Span },
                                                    new ForeFactorType[] { entity.Type },
                                                    entity.Semitype );

                                                    
                        }
                    }

                    foreach (string s in entity.Semi_new.Split(new char[] { '|' }))
                    {
                        if (s == "")
                            continue;
                        string[] ss = s.Split(new char[] { ';' });
                        newSemi[ss[0]] = ss[2];
                    }
                     
                    foreach (string station in newSemi.Keys)
                    {
                        string strOld = "";
                        if (oldSemi.ContainsKey(station))
                            strOld = oldSemi[station];
                        string strNew = newSemi[station];

                        if (strOld != strNew)
                        {
                            string l = entity.Id.ToString() + " : " + station + " : new -> " + strOld + " , old -> " + strNew;
                            Console.WriteLine(l);
                            Log(l);
                        }
                    }
                }

                beginDate = beginDate.AddDays(1);
            }


        }

        public static void printForeRealSemiValue(string stations, DateTime date, ForeClockType[] clocks,
            ForeSendpointType[] sendpoints, ForeSpanType[] spans, ForeFactorType[] factors, ForeSemiType semitype)
        {

            List<string> result = new List<string>();
            string connectionString = ConfigurationManager.AppSettings["NewConnectionString"];

            RealStationCompareRepository compareRepository = new RealStationCompareRepository(connectionString);
            ForeRealStationCompareEntity[] compareEntities = compareRepository.GetAllRecord(RealStationCompareType.Normal_Auto);
            Dictionary<string, string> compareDict = new Dictionary<string, string>();
            foreach (ForeRealStationCompareEntity entity in compareEntities)
            {
                compareDict[entity.ForeStation] = entity.RealStation;
            }

            ForeRepository normalCityForeRepository = ForeRepositoryFactory.NormalCityForeRepository(connectionString);
            RainRealRepository rainRepository = RainRealRepositoryFactory.AutoStationRainRealRepository(connectionString);
            TempRealRepository tempRepository = TempRealRepositoryFactory.AutoStationTempRealRepository(connectionString);

            ForeEntity[] entities = normalCityForeRepository.GetForeRecordWithDateRange(
                 date, date, clocks, spans, sendpoints, factors,
                semitype, false);

            ForeRealLinker linker = new ForeRealLinker();

            //result.Add("实况日期,实况类型,real,预报日期,fore,分级降水检验,晴雨(雪)检验,一般性降水检验,累加降水量检验");
            foreach (ForeEntity entity in entities)
            {
                if (entity.Type == ForeFactorType.wth)
                {
                    RainForeRealCompare comparer = linker.GetForeRelatedRainCondition(entity.Date, entity.Span, entity.Clock);
                    string real = rainRepository.GetValue(comparer.RealDate, comparer.RainType);
                    string stationReal = filterStation(real, compareDict[stations]);
                    string stationFore = filterStation(entity.Value, stations);
                    string stationSemi = filterStation(entity.Semi, stations);
                    if (stationSemi == "")
                    {
                        Log("empty semi");
                        continue;
                    }
                    WaterForecast forecate = new WaterForecast();
                    forecate.SetSemiResult(stationSemi, semitype);
                    result.Add(string.Join(",", new object[]{
                        comparer.RealDate.ToString("yyyyMMdd"),comparer.RainType.ToString(),stationReal.Replace(stations + ";", ""),
                        entity.Date.ToString("yyyyMMdd"),stationFore.Replace(stations + ";", ""),
                        forecate.PrecipitationLevelInspection.ToString(), forecate.WaterfallAmountInspection.ToString(),
                        forecate.WaterfallLevelInspection.ToString(), forecate.SumPrecipitationLevelInspection.ToString(),
                        }
                        ));

                }
            }
            
            foreach (string s in result)
            {
                Log(s);
            }
        }

        public static string filterStation(string value, string stations)
        {
            List<string> result = new List<string>();
            foreach (string station in stations.Split(new char[] { ';' }))
            {
                int startIndex = value.IndexOf(station);
                if (startIndex == -1)
                    return "";
                int endIndex = value.IndexOf('|', startIndex);
                if (endIndex < 0)
                    endIndex = value.Length - 1;
                string s = value.Substring(startIndex, endIndex - startIndex);
                result.Add(s);
            }
            if (result.Count > 1)
                return string.Join("|", result.ToArray());
            else
                return result[0];
        }


        public static void execute(string oldConnectionString, string newConnectionString)
        {
            //读取数据库中所有的表
            string selectTableNames = "select name from sysobjects where type = 'U'";

            SqlConnection connection = new SqlConnection(oldConnectionString);
            SqlDataReader reader = DBHelper.ExecuteReader(connection, selectTableNames);
            List<string> tableNames = new List<string>();
            while (reader.Read())
            {
                string tableName = (string)reader["name"];
                if (tableName.Contains("Normal") && tableName.Contains("2013") && (!tableName.Contains("_10_")))
                {
                    Console.WriteLine((string)reader["name"]);
                    tableNames.Add((string)reader["name"]);
                }
            }
            connection.Close();

            ITranferTableData transfer = new CityForeTransfer(oldConnectionString, newConnectionString);
            foreach(string table in tableNames)
            {
                transfer.TransformData(table);
            }
                                  
        }


    }

}
